[BLKBACK/BLKTAP] add sysfs throughput profiling to blk{back/tap}
authorJake Wires <jwires@xensource.com>
Wed, 21 Feb 2007 19:42:04 +0000 (11:42 -0800)
committerJake Wires <jwires@xensource.com>
Wed, 21 Feb 2007 19:42:04 +0000 (11:42 -0800)
linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c
linux-2.6-xen-sparse/drivers/xen/blkback/common.h
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c
linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c
linux-2.6-xen-sparse/drivers/xen/blktap/common.h
linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c

index f69bed26fe298ce9fc5fb5a2bc089e6f5a1e9279..c0cd61407009dfba1b4c2e7acc33f2090391c0e2 100644 (file)
@@ -491,6 +491,12 @@ static void dispatch_rw_block_io(blkif_t *blkif,
        for (i = 0; i < nbio; i++)
                submit_bio(operation, biolist[i]);
 
+        if (operation == READ) {
+                blkif->st_rd_sect += preq.nr_sects;
+        } else if (operation == WRITE) {
+                blkif->st_wr_sect += preq.nr_sects;
+        }
+
        return;
 
  fail_put_bio:
index 67d5d44a09aee2cfd310ae6a60ae392f0337e18a..30f938956d8947e98985c7e0190affd99122dd4e 100644 (file)
@@ -88,6 +88,8 @@ typedef struct blkif_st {
        int                 st_wr_req;
        int                 st_oo_req;
        int                 st_br_req;
+        int                 st_rd_sect;
+        int                 st_wr_sect;
 
        wait_queue_head_t waiting_to_free;
 
index 3c89453030e7446a59773a35b0e80f913e2fbe5b..0c688e973fef179d6baedba67f2cace046a3b3f8 100644 (file)
@@ -111,16 +111,20 @@ static void update_blkif_status(blkif_t *blkif)
        }                                                               \
        DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
 
-VBD_SHOW(oo_req, "%d\n", be->blkif->st_oo_req);
-VBD_SHOW(rd_req, "%d\n", be->blkif->st_rd_req);
-VBD_SHOW(wr_req, "%d\n", be->blkif->st_wr_req);
-VBD_SHOW(br_req, "%d\n", be->blkif->st_br_req);
+VBD_SHOW(oo_req,  "%d\n", be->blkif->st_oo_req);
+VBD_SHOW(rd_req,  "%d\n", be->blkif->st_rd_req);
+VBD_SHOW(wr_req,  "%d\n", be->blkif->st_wr_req);
+VBD_SHOW(br_req,  "%d\n", be->blkif->st_br_req);
+VBD_SHOW(rd_sect, "%d\n", be->blkif->st_rd_sect);
+VBD_SHOW(wr_sect, "%d\n", be->blkif->st_wr_sect);
 
 static struct attribute *vbdstat_attrs[] = {
        &dev_attr_oo_req.attr,
        &dev_attr_rd_req.attr,
        &dev_attr_wr_req.attr,
        &dev_attr_br_req.attr,
+       &dev_attr_rd_sect.attr,
+       &dev_attr_wr_sect.attr,
        NULL
 };
 
index d9e759eaf5d75be31a3443480af7fcf51e91a0fc..3aaa1f561f71cadc309a251f654a7dd4425b7c67 100644 (file)
@@ -1195,7 +1195,7 @@ static void dispatch_rw_block_io(blkif_t *blkif,
        int op, operation = (req->operation == BLKIF_OP_WRITE) ? WRITE : READ;
        struct gnttab_map_grant_ref map[BLKIF_MAX_SEGMENTS_PER_REQUEST*2];
        unsigned int nseg;
-       int ret, i;
+       int ret, i, nr_sects = 0;
        tap_blkif_t *info;
        uint64_t sector;
        blkif_request_t *target;
@@ -1291,6 +1291,9 @@ static void dispatch_rw_block_io(blkif_t *blkif,
                                          req->seg[i].gref, blkif->domid);
                        op++;
                }
+
+               nr_sects += (req->seg[i].last_sect - 
+                            req->seg[i].first_sect + 1);
        }
 
        ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map, op);
@@ -1403,6 +1406,13 @@ static void dispatch_rw_block_io(blkif_t *blkif,
        target->id = usr_idx;
        wmb(); /* blktap_poll() reads req_prod_pvt asynchronously */
        info->ufe_ring.req_prod_pvt++;
+
+       if (operation == READ) {
+               blkif->st_rd_sect += nr_sects;
+       } else if (operation == WRITE) {
+               blkif->st_wr_sect += nr_sects;
+       }
+
        return;
 
  fail_flush:
index 019f7ba58b24d4dc9d27757eb7f978b6f2bc89c2..de551f136d5777dff6b6d47dbdd499c7c2d21198 100644 (file)
@@ -76,6 +76,8 @@ typedef struct blkif_st {
        int                 st_rd_req;
        int                 st_wr_req;
        int                 st_oo_req;
+       int                 st_rd_sect;
+       int                 st_wr_sect;
 
        wait_queue_head_t waiting_to_free;
 
index 3f3344b3bd9c699bca45bba3488ab34706453c5e..14a8dd404161df6dec5bcbc1dc48d589854611bd 100644 (file)
@@ -112,6 +112,74 @@ static int blktap_name(blkif_t *blkif, char *buf)
        return 0;
 }
 
+/****************************************************************
+ *  sysfs interface for VBD I/O requests
+ */
+
+#define VBD_SHOW(name, format, args...)                                        \
+       static ssize_t show_##name(struct device *_dev,                 \
+                                  struct device_attribute *attr,       \
+                                  char *buf)                           \
+       {                                                               \
+               struct xenbus_device *dev = to_xenbus_device(_dev);     \
+               struct backend_info *be = dev->dev.driver_data;         \
+                                                                       \
+               return sprintf(buf, format, ##args);                    \
+       }                                                               \
+       DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
+
+VBD_SHOW(tap_oo_req,  "%d\n", be->blkif->st_oo_req);
+VBD_SHOW(tap_rd_req,  "%d\n", be->blkif->st_rd_req);
+VBD_SHOW(tap_wr_req,  "%d\n", be->blkif->st_wr_req);
+VBD_SHOW(tap_rd_sect, "%d\n", be->blkif->st_rd_sect);
+VBD_SHOW(tap_wr_sect, "%d\n", be->blkif->st_wr_sect);
+
+static struct attribute *tapstat_attrs[] = {
+       &dev_attr_tap_oo_req.attr,
+       &dev_attr_tap_rd_req.attr,
+       &dev_attr_tap_wr_req.attr,
+       &dev_attr_tap_rd_sect.attr,
+       &dev_attr_tap_wr_sect.attr,
+       NULL
+};
+
+static struct attribute_group tapstat_group = {
+       .name = "statistics",
+       .attrs = tapstat_attrs,
+};
+
+int xentap_sysfs_addif(struct xenbus_device *dev)
+{
+       return sysfs_create_group(&dev->dev.kobj, &tapstat_group);
+}
+
+void xentap_sysfs_delif(struct xenbus_device *dev)
+{
+       sysfs_remove_group(&dev->dev.kobj, &tapstat_group);
+}
+
+static int blktap_remove(struct xenbus_device *dev)
+{
+       struct backend_info *be = dev->dev.driver_data;
+
+       if (be->backend_watch.node) {
+               unregister_xenbus_watch(&be->backend_watch);
+               kfree(be->backend_watch.node);
+               be->backend_watch.node = NULL;
+       }
+       if (be->blkif) {
+               if (be->blkif->xenblkd)
+                       kthread_stop(be->blkif->xenblkd);
+               signal_tapdisk(be->blkif->dev_num);
+               tap_blkif_free(be->blkif);
+               be->blkif = NULL;
+       }
+       xentap_sysfs_delif(be->dev);
+       kfree(be);
+       dev->dev.driver_data = NULL;
+       return 0;
+}
+
 static void tap_update_blkif_status(blkif_t *blkif)
 { 
        int err;
@@ -137,6 +205,13 @@ static void tap_update_blkif_status(blkif_t *blkif)
                return;
        }
 
+       err = xentap_sysfs_addif(blkif->be->dev);
+       if (err) {
+               xenbus_dev_fatal(blkif->be->dev, err, 
+                                "creating sysfs entries");
+               return;
+       }
+
        blkif->xenblkd = kthread_run(tap_blkif_schedule, blkif, name);
        if (IS_ERR(blkif->xenblkd)) {
                err = PTR_ERR(blkif->xenblkd);
@@ -146,27 +221,6 @@ static void tap_update_blkif_status(blkif_t *blkif)
        }
 }
 
-static int blktap_remove(struct xenbus_device *dev)
-{
-       struct backend_info *be = dev->dev.driver_data;
-
-       if (be->backend_watch.node) {
-               unregister_xenbus_watch(&be->backend_watch);
-               kfree(be->backend_watch.node);
-               be->backend_watch.node = NULL;
-       }
-       if (be->blkif) {
-               if (be->blkif->xenblkd)
-                       kthread_stop(be->blkif->xenblkd);
-               signal_tapdisk(be->blkif->dev_num);
-               tap_blkif_free(be->blkif);
-               be->blkif = NULL;
-       }
-       kfree(be);
-       dev->dev.driver_data = NULL;
-       return 0;
-}
-
 /**
  * Entry point to this code when a new device is created.  Allocate
  * the basic structures, and watch the store waiting for the